home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xlock / worm.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  5KB  |  207 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)worm.c 12.1 95/05/09 XLOCK";
  3. #endif
  4. /*-
  5.  * worm.c - draw wiggly worms.
  6.  *
  7.  * Copyright (c) 1991 by Patrick J. Naughton.
  8.  *
  9.  * See xlock.c for copying information.
  10.  *
  11.  * Revision History:
  12.  * 27-Sep-91: got rid of all malloc calls since there were no calls to free().
  13.  * 25-Sep-91: Integrated into X11R5 contrib xlock.
  14.  *
  15.  * Adapted from a concept in the Dec 87 issue of Scientific American.
  16.  *
  17.  * SunView version: Brad Taylor (brad@sun.com)
  18.  * X11 version: Dave Lemke (lemke@ncd.com)
  19.  * xlock version: Boris Putanec (bp@cs.brown.edu)
  20.  *
  21.  * This code is a static memory pig... like almost 200K... but as contributed
  22.  * it leaked at a massive rate, so I made everything static up front... feel
  23.  * free to contribute the proper memory management code.
  24.  * 
  25.  */
  26.  
  27. #include    "xlock.h"
  28. #include    <math.h>
  29.  
  30. #define MAXCOLORS 64
  31. #define MAXWORMS 64
  32. #define CIRCSIZE 2
  33. #define MAXWORMLEN 50
  34.  
  35. #define PI 3.14159265358979323844
  36. #define SEGMENTS  36
  37. static int  sintab[SEGMENTS];
  38. static int  costab[SEGMENTS];
  39. static int  init_table = 0;
  40.  
  41. typedef struct {
  42.     int         xcirc[MAXWORMLEN];
  43.     int         ycirc[MAXWORMLEN];
  44.     int         dir;
  45.     int         tail;
  46.     int         x;
  47.     int         y;
  48. }           wormstuff;
  49.  
  50. typedef struct {
  51.     int         xsize;
  52.     int         ysize;
  53.     int         wormlength;
  54.     int         monopix;
  55.     int         nc;
  56.     int         nw;
  57.     wormstuff   worm[MAXWORMS];
  58.     XRectangle  rects[MAXCOLORS][MAXWORMS];
  59.     int         size[MAXCOLORS];
  60. }           wormstruct;
  61.  
  62. static wormstruct worms[MAXSCREENS];
  63.  
  64. int
  65. round(x)
  66.     float       x;
  67. {
  68. #ifdef sco
  69.     return ((int) x);
  70. #else
  71.     return ((int) rint((double) x));
  72. #endif
  73. }
  74.  
  75.  
  76. void
  77. worm_doit(win, wp, which, color)
  78.     Window      win;
  79.     wormstruct *wp;
  80.     int         which;
  81.     unsigned long color;
  82. {
  83.     wormstuff  *ws = &wp->worm[which];
  84.     int         x, y;
  85.  
  86.     ws->tail++;
  87.     if (ws->tail == wp->wormlength)
  88.     ws->tail = 0;
  89.  
  90.     x = ws->xcirc[ws->tail];
  91.     y = ws->ycirc[ws->tail];
  92.     XClearArea(dsp, win, x, y, CIRCSIZE, CIRCSIZE, False);
  93.  
  94.     if (random() & 1) {
  95.     ws->dir = (ws->dir + 1) % SEGMENTS;
  96.     } else {
  97.     ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS;
  98.     }
  99.  
  100.     x = (ws->x + costab[ws->dir] + wp->xsize) % wp->xsize;
  101.     y = (ws->y + sintab[ws->dir] + wp->ysize) % wp->ysize;
  102.  
  103.     ws->xcirc[ws->tail] = x;
  104.     ws->ycirc[ws->tail] = y;
  105.     ws->x = x;
  106.     ws->y = y;
  107.  
  108.     wp->rects[color][wp->size[color]].x = x;
  109.     wp->rects[color][wp->size[color]].y = y;
  110.     wp->size[color]++;
  111. }
  112.  
  113.  
  114. void
  115. initworm(win)
  116.     Window      win;
  117. {
  118.     int         i, j;
  119.     wormstruct *wp = &worms[screen];
  120.     XWindowAttributes xwa;
  121.  
  122.     wp->nc = Scr[screen].npixels;
  123.     if (wp->nc > MAXCOLORS)
  124.     wp->nc = MAXCOLORS;
  125.  
  126.     wp->nw = batchcount;
  127.     if (wp->nw > MAXWORMS)
  128.     wp->nw = MAXWORMS;
  129.  
  130.     if (!init_table) {
  131.     init_table = 1;
  132.     for (i = 0; i < SEGMENTS; i++) {
  133.         sintab[i] = round(CIRCSIZE * sin(i * 2 * PI / SEGMENTS));
  134.         costab[i] = round(CIRCSIZE * cos(i * 2 * PI / SEGMENTS));
  135.     }
  136.     }
  137.     XGetWindowAttributes(dsp, win, &xwa);
  138.     wp->xsize = xwa.width;
  139.     wp->ysize = xwa.height;
  140.  
  141.     if (xwa.width < 100) {
  142.     wp->monopix = BlackPixel(dsp, screen);
  143.     wp->wormlength = MAXWORMLEN / 10;
  144.     } else {
  145.     wp->monopix = WhitePixel(dsp, screen);
  146.     wp->wormlength = MAXWORMLEN;
  147.     }
  148.  
  149.     for (i = 0; i < wp->nc; i++) {
  150.     for (j = 0; j < wp->nw / wp->nc + 1; j++) {
  151.         wp->rects[i][j].width = CIRCSIZE;
  152.         wp->rects[i][j].height = CIRCSIZE;
  153.     }
  154.     }
  155.     bzero(wp->size, wp->nc * sizeof(int));
  156.  
  157.     for (i = 0; i < wp->nw; i++) {
  158.     for (j = 0; j < wp->wormlength; j++) {
  159.         wp->worm[i].xcirc[j] = wp->xsize / 2;
  160.         wp->worm[i].ycirc[j] = wp->ysize / 2;
  161.     }
  162.     wp->worm[i].dir = (unsigned) random() % SEGMENTS;
  163.     wp->worm[i].tail = 0;
  164.     wp->worm[i].x = wp->xsize / 2;
  165.     wp->worm[i].y = wp->ysize / 2;
  166.     }
  167.  
  168.     XClearWindow(dsp, win);
  169. }
  170.  
  171.  
  172. void
  173. drawworm(win)
  174.     Window      win;
  175. {
  176.     int         i;
  177.     wormstruct *wp = &worms[screen];
  178.     unsigned int wcolor;
  179.     static unsigned int chromo = 0;
  180.  
  181.     bzero(wp->size, wp->nc * sizeof(int));
  182.  
  183.     for (i = 0; i < wp->nw; i++) {
  184.     if (!mono && wp->nc > 2) {
  185.         wcolor = (i + chromo) % wp->nc;
  186.  
  187.         worm_doit(win, wp, i, wcolor);
  188.     } else
  189.         worm_doit(win, wp, i, 0);
  190.     }
  191.  
  192.     if (!mono && wp->nc > 2) {
  193.     for (i = 0; i < wp->nc; i++) {
  194.         XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[i]);
  195.         XFillRectangles(dsp, win, Scr[screen].gc, wp->rects[i],
  196.                 wp->size[i]);
  197.     }
  198.     } else {
  199.     XSetForeground(dsp, Scr[screen].gc, wp->monopix);
  200.     XFillRectangles(dsp, win, Scr[screen].gc, wp->rects[0],
  201.             wp->size[0]);
  202.     }
  203.  
  204.     if (++chromo == wp->nc)
  205.     chromo = 0;
  206. }
  207.